package com.campus.schedule.timer;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.campus.schedule.entity.Merchant;
import com.campus.schedule.entity.MerchantBusinessHours;
import com.campus.schedule.service.MerchantService;
import com.campus.schedule.service.MerchantBusinessHoursService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 商户营业状态自动更新定时任务服务
 */
@Service
@Slf4j
public class MerchantStatusScheduleService {

    @Autowired
    private MerchantService merchantService;
    
    @Autowired
    private MerchantBusinessHoursService merchantBusinessHoursService;
    
    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");

    /**
     * 每分钟检查并更新商户营业状态
     * 只更新closeMethod=0（系统自动关闭）的商户
     */
    @Scheduled(cron = "0 * * * * ?") // 每分钟执行一次
    public void updateMerchantStatus() {
        try {
            log.debug("开始检查商户营业状态...");
            
            // 获取当前时间
            LocalDateTime now = LocalDateTime.now();
            LocalTime currentTime = now.toLocalTime();
            int currentWeekday = now.getDayOfWeek().getValue(); // 1=周一, 7=周日
            
            // 查询所有closeMethod=0的商户
            LambdaQueryWrapper<Merchant> merchantQuery = new LambdaQueryWrapper<>();
            merchantQuery.eq(Merchant::getCloseMethod, 0);
            List<Merchant> merchants = merchantService.list(merchantQuery);
            
            if (merchants.isEmpty()) {
                log.debug("没有需要自动更新状态的商户");
                return;
            }
            
            log.info("开始检查 {} 个商户的营业状态", merchants.size());
            
            int updatedCount = 0;
            
            for (Merchant merchant : merchants) {
                try {
                    // 获取商户的营业时间设置
                    LambdaQueryWrapper<MerchantBusinessHours> hoursQuery = new LambdaQueryWrapper<>();
                    hoursQuery.eq(MerchantBusinessHours::getMerchantId, merchant.getId());
                    List<MerchantBusinessHours> businessHoursList = merchantBusinessHoursService.list(hoursQuery);
                    
                    if (businessHoursList.isEmpty()) {
                        // 没有设置营业时间，默认设为休息中
                        if (merchant.getStatus() != 0) {
                            updateMerchantStatus(merchant.getId(), 0);
                            updatedCount++;
                            log.info("商户 {} 没有设置营业时间，状态更新为休息中", merchant.getName());
                        }
                        continue;
                    }
                    
                    // 检查是否在营业时间内
                    boolean isOpen = isWithinBusinessHours(businessHoursList, currentTime, currentWeekday);
                    
                    // 更新状态（1-营业中，0-休息中）
                    int newStatus = isOpen ? 1 : 0;
                    if (merchant.getStatus() != newStatus) {
                        updateMerchantStatus(merchant.getId(), newStatus);
                        updatedCount++;
                        log.info("商户 {} 状态更新为: {}", merchant.getName(), newStatus == 1 ? "营业中" : "休息中");
                    }
                    
                } catch (Exception e) {
                    log.error("更新商户 {} 状态时发生错误", merchant.getName(), e);
                }
            }
            
            if (updatedCount > 0) {
                log.info("商户营业状态检查完成，共更新了 {} 个商户的状态", updatedCount);
            } else {
                log.debug("商户营业状态检查完成，无需更新");
            }
            
        } catch (Exception e) {
            log.error("商户营业状态定时任务执行失败", e);
        }
    }
    
    /**
     * 检查当前时间是否在营业时间内
     * @param businessHoursList 营业时间列表
     * @param currentTime 当前时间
     * @param currentWeekday 当前星期几（1=周一, 7=周日）
     * @return true-营业中，false-休息中
     */
    private boolean isWithinBusinessHours(List<MerchantBusinessHours> businessHoursList, 
                                         LocalTime currentTime, int currentWeekday) {
        
        for (MerchantBusinessHours hours : businessHoursList) {
            try {
                // 检查今天是否营业
                String weekdays = hours.getWeekdays();
                if (weekdays == null || weekdays.length() != 7) {
                    log.warn("商户营业时间weekdays格式错误: {}", weekdays);
                    continue;
                }
                
                // 将Java的星期几（1=周一）转换为weekdays字符串的索引（0=周一）
                int weekdayIndex = currentWeekday - 1;
                if (weekdayIndex < 0 || weekdayIndex >= 7) {
                    continue;
                }
                
                // 检查今天是否营业（1-营业，0-休息）
                char todayStatus = weekdays.charAt(weekdayIndex);
                if (todayStatus != '1') {
                    continue; // 今天不营业，检查下一个时间段
                }
                
                // 解析营业时间
                LocalTime startTime = LocalTime.parse(hours.getStartTime(), TIME_FORMATTER);
                LocalTime endTime = LocalTime.parse(hours.getEndTime(), TIME_FORMATTER);
                
                // 检查当前时间是否在营业时间内
                if (isTimeInRange(currentTime, startTime, endTime)) {
                    return true; // 在营业时间内
                }
                
            } catch (Exception e) {
                log.error("解析营业时间失败: startTime={}, endTime={}", 
                         hours.getStartTime(), hours.getEndTime(), e);
            }
        }
        
        return false; // 不在任何营业时间内
    }
    
    /**
     * 检查时间是否在指定范围内
     * @param currentTime 当前时间
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return true-在范围内，false-不在范围内
     */
    private boolean isTimeInRange(LocalTime currentTime, LocalTime startTime, LocalTime endTime) {
        // 处理跨天的情况（如22:00-02:00）
        if (endTime.isBefore(startTime)) {
            // 跨天营业：当前时间在开始时间之后或结束时间之前
            return currentTime.isAfter(startTime) || currentTime.isBefore(endTime) || 
                   currentTime.equals(startTime) || currentTime.equals(endTime);
        } else {
            // 同一天营业：当前时间在开始和结束时间之间
            return (currentTime.isAfter(startTime) || currentTime.equals(startTime)) && 
                   (currentTime.isBefore(endTime) || currentTime.equals(endTime));
        }
    }
    
    /**
     * 更新商户状态
     * @param merchantId 商户ID
     * @param status 新状态（1-营业中，0-休息中）
     */
    private void updateMerchantStatus(Integer merchantId, Integer status) {
        LambdaUpdateWrapper<Merchant> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Merchant::getId, merchantId)
                    .set(Merchant::getStatus, status)
                    .set(Merchant::getUpdateTime, LocalDateTime.now());
        
        merchantService.update(updateWrapper);
    }
}